﻿//-------------------------------------
// WBFSSync - WBFSSync.exe
//
// Copyright 2009 Caian (ÔmΣga Frøst) <frost.omega@hotmail.com> :
//
// WBFSSync is Licensed under the terms of the Microsoft Reciprocal License (Ms-RL)
//
// AeroMenuButton.cs:
//
// Controle que imita o botão do menu do Explorer
//
//-------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace WBFSSync.AeroControls
{
    public enum AeroMenuButtonMode
    {
        Normal,
        DropDownButton,
        FullDropDown,
        Glow,
    }

    public partial class AeroMenuButton : UserControl
    {
        //----------------------- Constantes

        //----------------------- Variáveis

        static SolidBrush ForeBrush = new SolidBrush(Color.FromArgb(76, 96, 122));

        Point mousePosition = new Point(-1, -1);
        Boolean mouseLeftDown = false;
        Boolean mouseOverControl = false;

        Boolean dropDownClick = false;

        ToolTip tooltip = new ToolTip();

        int text_x = 0;
        int icon_x = 0;

        int text_width = 0;
        public Int32 CaptionWidth { get { return text_width; } }

        int border = 4;
        public Int32 Border { get { return border; } set { border = value; OnBorderChanged(); } }

        string caption = "";
        public String Caption { get { return caption; } set { caption = value; OnCaptionChanged(); } }

        Image icon = null;
        public Image Icon { get { return icon; } set { icon = value; OnIconVisibleChanged(); } }

        bool showIcon = true;
        public Boolean ShowIcon { get { return showIcon; } set { showIcon = value; OnIconVisibleChanged(); } }

        bool autoSize = true;
        public new Boolean AutoSize { get { return autoSize; } set { autoSize = value; OnAutoSizeChanged(); } }

        ContextMenuStrip dropdownMenu = null;
        public ContextMenuStrip DropDownMenu { get { return dropdownMenu; } set { dropdownMenu = value; } }

        AeroMenuButtonMode buttonMode = AeroMenuButtonMode.Normal;
        public AeroMenuButtonMode ButtonMode { get { return buttonMode; } set { buttonMode = value; } }

        public Boolean ShowToolTip { get { return tooltip.Active; } set { tooltip.Active = true; } }

        string tooltipText = "";
        public String ToolTipText { get { return tooltipText; } set { tooltipText = value; OnToolTipTextChanged(); } }

        //----------------------- Rotinas

        public AeroMenuButton()
        {
            DoubleBuffered = true;
            BackColor = Color.Transparent;
            InitializeComponent();
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            mouseOverControl = true;
            base.OnMouseEnter(e);
            Invalidate();
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            mouseOverControl = false;
            mousePosition.X = 0;
            mousePosition.Y = 0;
            base.OnMouseLeave(e);
            Invalidate();
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            mousePosition = e.Location;
            base.OnMouseMove(e);
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left) mouseLeftDown = true;
            base.OnMouseDown(e);

            if (buttonMode == AeroMenuButtonMode.DropDownButton)
            {
                if (e.Location.X >= Width - 18)
                {
                    dropDownClick = true;
                    if (dropdownMenu != null) dropdownMenu.Show(this, 0, Height);
                    return;
                }
            }
            
            Invalidate();
        }

        protected override void OnClick(EventArgs e)
        {
            if (!dropDownClick)
                base.OnClick(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                dropDownClick = false;
                mouseLeftDown = false;

                if ((buttonMode == AeroMenuButtonMode.FullDropDown) && (dropdownMenu != null))
                    dropdownMenu.Show(this, 0, Height);
            }
            base.OnMouseUp(e);
            Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            if (!Skin.SkinReady)
            {
                e.Graphics.DrawLine(Pens.Blue, 0, 0, Width, Height);
                e.Graphics.DrawLine(Pens.Blue, Width, 0, 0, Height);

                e.Graphics.DrawLine(Pens.Blue, 0, 0, Width, 0);
                e.Graphics.DrawLine(Pens.Blue, 0, Height - 1, Width, Height - 1);
                e.Graphics.DrawLine(Pens.Blue, 0, 0, 0, Height);
                e.Graphics.DrawLine(Pens.Blue, Width - 1, 0, Width - 1, Height);
                return;
            }

            e.Graphics.SmoothingMode = SmoothingMode.HighSpeed;
            e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
            e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

            DrawBackground(e.Graphics);

            if (mouseOverControl)
            {
                if (mouseLeftDown)
                {
                    if (showIcon && (icon != null)) e.Graphics.DrawImage(icon, icon_x + 3, 5, 16, 16);
                    if (Skin.CaptionFont != null) e.Graphics.DrawString(caption, Skin.CaptionFont, ForeBrush, text_x + 4,
                         13 - Skin.CaptionFont.Height / 2);

                    switch (buttonMode)
                    {
                        case AeroMenuButtonMode.FullDropDown:
                            e.Graphics.DrawImage(Skin.menu_button_arrow, Width - border - 11, 11, 9, 5);
                            break;
                        case AeroMenuButtonMode.DropDownButton:
                            e.Graphics.DrawImage(Skin.menu_button_arrow, Width - 13, 11, 9, 5);
                            break;
                    }
                }
                else
                {
                    if (showIcon && (icon != null)) e.Graphics.DrawImage(icon, icon_x + 2, 4, 16, 16);
                    if (Skin.CaptionFont != null) e.Graphics.DrawString(caption, Skin.CaptionFont, ForeBrush, text_x + 3,
                         12 - Skin.CaptionFont.Height / 2);

                    switch (buttonMode)
                    {
                        case AeroMenuButtonMode.FullDropDown:
                            e.Graphics.DrawImage(Skin.menu_button_arrow, Width - border - 12, 10, 9, 5);
                            break;
                        case AeroMenuButtonMode.DropDownButton:
                            e.Graphics.DrawImage(Skin.menu_button_arrow, Width - 14, 10, 9, 5);
                            break;
                    }
                }
            }
            else
            {
                switch (buttonMode)
                {
                    case AeroMenuButtonMode.FullDropDown:
                        e.Graphics.DrawImage(Skin.menu_button_arrow, Width - border - 12, 10, 9, 5);
                        break;
                    case AeroMenuButtonMode.DropDownButton:
                        e.Graphics.DrawImage(Skin.menu_button_arrow, Width - 14, 10, 9, 5);
                        break;
                }

                if (showIcon && (icon != null)) e.Graphics.DrawImage(icon, icon_x + 2, 4, 16, 16);
                if (Skin.CaptionFont != null) e.Graphics.DrawString(caption, Skin.CaptionFont, ForeBrush, text_x + 3,
                     12 - Skin.CaptionFont.Height / 2);
            }

            base.OnPaint(e);
        }

        protected void DrawBackground(Graphics g)
        {
            if (mouseOverControl)
            {
                if (mouseLeftDown)
                {
                    switch (buttonMode)
                    {
                        case AeroMenuButtonMode.Normal:         //Idênticos
                        case AeroMenuButtonMode.FullDropDown:
                        case AeroMenuButtonMode.Glow:
                            g.DrawImage(Skin.menu_button_l_c, 0, 0, 4, 24);
                            g.DrawImage(Skin.menu_button_m_c, 4, 0, Width - 8, 24);
                            g.DrawImage(Skin.menu_button_r_normal_c, Width - 4, 0, 4, 24);
                            break;
                        case AeroMenuButtonMode.DropDownButton:
                            g.DrawImage(Skin.menu_button_l_c, 0, 0, 4, 24);
                            g.DrawImage(Skin.menu_button_m_c, 4, 0, Width - 8, 24);
                            g.DrawImage(Skin.menu_button_r_dropdown_c, Width - 20, 0, 20, 24);
                            break;
                    }
                }
                else
                {
                    switch (buttonMode)
                    {
                        case AeroMenuButtonMode.Normal:         //Idênticos
                        case AeroMenuButtonMode.FullDropDown:
                            g.DrawImage(Skin.menu_button_l_o, 0, 0, 4, 24);
                            g.DrawImage(Skin.menu_button_m_o, 4, 0, Width - 8, 24);
                            g.DrawImage(Skin.menu_button_r_normal_o, Width - 4, 0, 4, 24);
                            break;
                        case AeroMenuButtonMode.DropDownButton:
                            g.DrawImage(Skin.menu_button_l_o, 0, 0, 4, 24);
                            g.DrawImage(Skin.menu_button_m_o, 4, 0, Width - 8, 24);
                            g.DrawImage(Skin.menu_button_r_dropdown_o, Width - 20, 0, 20, 24);
                            break;
                        case AeroMenuButtonMode.Glow:
                            g.DrawImage(Skin.menu_button_warning_l_o, 0, 0, 4, 24);
                            g.DrawImage(Skin.menu_button_warning_m_o, 4, 0, Width - 8, 24);
                            g.DrawImage(Skin.menu_button_warning_r_o, Width - 4, 0, 4, 24);
                            break;
                    }
                }
            }

        }

        //----------------------- On's

        void OnBorderChanged()
        {
            if (showIcon)
            {
                icon_x = border;
                text_x = icon_x + 20;
            }
            else
            {
                text_x = border;
            }

            if (autoSize)
            {
                int w = text_x + text_width + border;
                if (buttonMode == AeroMenuButtonMode.DropDownButton) w += 18;
                else if (buttonMode == AeroMenuButtonMode.FullDropDown) w += 14;
                Width = w;
            }

            Invalidate();
        }

        void OnCaptionChanged()
        {
            text_width = TextRenderer.MeasureText(caption, Skin.CaptionFont).Width;
            
            if (autoSize)
            {
                int w = text_x + text_width + border;
                if (buttonMode == AeroMenuButtonMode.DropDownButton) w += 18;
                else if (buttonMode == AeroMenuButtonMode.FullDropDown) w += 14;
                Width = w;
            }

            Invalidate();
        }

        void OnAutoSizeChanged()
        {
            if (autoSize)
            {
                int w = text_x + text_width + border;
                if (buttonMode == AeroMenuButtonMode.DropDownButton) w += 18;
                else if (buttonMode == AeroMenuButtonMode.FullDropDown) w += 14;
                Width = w;
            }

            Invalidate();
        }

        void OnIconVisibleChanged()
        {
            if (showIcon)
            {
                icon_x = border;
                text_x = icon_x + 20;
            }
            else
            {
                text_x = border;
            }

            if (autoSize)
            {
                int w = text_x + text_width + border;
                if (buttonMode == AeroMenuButtonMode.DropDownButton) w += 18;
                else if (buttonMode == AeroMenuButtonMode.FullDropDown) w += 14;
                Width = w;
            }

            Invalidate();
        }

        void OnToolTipTextChanged()
        {
            tooltip.SetToolTip(this, tooltipText);
        }
    }
}
